﻿using Entity.Models;
using HuaRunInterface.Comm;
using HuaRunInterface.Controllers;
using HuaRunInterface.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.PTG;
using Org.BouncyCastle.Asn1.Ocsp;
using System.Collections.Generic;
using Utility;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace HuaRunLanYanInterface.Controllers.RollbackControllers
{
    /// <summary>
    /// 余额同步
    /// </summary>
    [Route("command/meterCmd")]
    [ApiController]
    public class RemainMoneySyncController : ControllerBase
    {
        // POST api/<RemainSync>
        [HttpPost]
        public object Post([FromBody] object value)
        {
            return Remain(value);
        }

        private object Remain(object dto)
        {
            ReturnRollbackModel rd = new ReturnRollbackModel();
            CommandResponseModel mr = new CommandResponseModel();
            string errMsg = "";
            JObject jb = JObject.Parse(dto.ToString());
            Utility.WriteLog.WriteBalanceLogsFile($"command meter  Cmd :{dto}");
            try
            {
                if (jb["meterCommandCode"].ToString() == "SYNC_BALANCE")
                {
                    string conn = Global.Configuration["ConnectionStrings:DDb"];
                    using (Entity.DBContext context = Entity.BaseContext.CreateContext(conn))
                    {
                        MeterInfo? v = context.meterInfos.Where(p => p.uniqueDeviceIdentifier == jb["uniqueDeviceIdentifier"].ToString()).FirstOrDefault();
                        RTUInfo? rv = context.rTUInfos.Where(p => p.uniqueDeviceIdentifier == jb["uniqueDeviceIdentifier"].ToString()).FirstOrDefault();
                        if (v != null)
                        {
                            ReqRemainMoneyModel dto2 = dto.ToString().JSONStringToObject<ReqRemainMoneyModel>();
                            mr.sequence = dto2.sequence;
                            if (BalanceSyncController.Balance != null)
                            {
                                BalanceSyncController.Balance(dto2);
                                rd.code = 200;
                            }
                        }
                        if (rv != null)
                        {
                            ReqRtuRemainMoneyModel dto2 = dto.ToString().JSONStringToObject<ReqRtuRemainMoneyModel>();
                            mr.sequence = dto2.sequence;
                            if (BalanceSyncController.Balance != null)
                            {
                                BalanceSyncController.Balance(dto2);
                                rd.code = 200;
                            }
                            #region
                            //ReqRtuRemainMoneyModel dto2 = dto.ToString().JSONStringToObject<ReqRtuRemainMoneyModel>();
                            //rd.code = 200;

                            //RealDataInfo real = context.realDataInfos.Where(p => p.deviceCode == rv.deviceCode).FirstOrDefault();
                            ////下发充值和开关阀指令
                            //string apiInterface = "api/Conf/CtrlData/AddMulti";
                            //List<CtrlCommandModel> list = new List<CtrlCommandModel>();
                            //CtrlCommandModel data = new CtrlCommandModel();
                            //data.target_comm_no = rv.deviceCode;
                            //data.ctrl_time = DateTime.Now;
                            //data.ctrl_timeout = DateTime.Now.AddDays(3);
                            //if (dto2.cmdParam.valveControlState == "OPEN")
                            //{
                            //    data.ctrl_type = "iotmeterv1.common.releaseforce";
                            //}
                            //else
                            //{
                            //    data.ctrl_type = "iotmeterv1.common.setvalveoff";
                            //}
                            //if (dto2.cmdParam.valveControlState != "DEFAULT"
                            //    && ((dto2.cmdParam.valveControlState == "OPEN" && real.ValveState == 1)
                            //    || (dto2.cmdParam.valveControlState != "OPEN" && real.ValveState == 0)))
                            //{
                            //    list.Add(data);
                            //}
                            //List<RechargeInfo> recharges = context.rechargeInfos.Where(p => p.deviceCode == rv.deviceCode).OrderByDescending(p => p.RechargeTime).ToList();
                            //CtrlCommandModel data2 = new CtrlCommandModel();
                            //data2.target_comm_no = rv.deviceCode;
                            //data2.ctrl_time = DateTime.Now;
                            //data2.ctrl_timeout = DateTime.Now.AddDays(3);
                            //data2.ctrl_type = "iotmeterv1.prepay.remotecharge";
                            //remote_charge_param p = new remote_charge_param();
                            //p.charge_times = recharges.Count + 1;
                            //p.charge_value = dto2.cmdParam.recentRechargeAmount.Value;
                            //p.total_value = recharges.Sum(p => p.RechargeMoney) + dto2.cmdParam.recentRechargeAmount.Value;
                            //data2.ctrl_data = p.SerializerObjectToString();
                            //DateTime recentTime = dto2.cmdParam.recentPaymentTime.Value.ToString().ConvertStringToDateTime();
                            //if (recharges.Count == 0 || recharges.Where(p => p.recentPaymentTime == dto2.cmdParam.recentPaymentTime.ToString()).FirstOrDefault() == null)
                            //{
                            //    list.Add(data2);
                            //    RechargeInfo recharge = new RechargeInfo();
                            //    recharge.deviceCode = rv.deviceCode;
                            //    recharge.RechargeTime = recentTime;
                            //    recharge.recentPaymentTime = dto2.cmdParam.recentPaymentTime.ToString();
                            //    recharge.RechargeMoney = dto2.cmdParam.recentRechargeAmount.Value;
                            //    context.rechargeInfos.Add(recharge);
                            //    context.SaveChanges();
                            //}
                            //CtrlCommandModel data3 = new CtrlCommandModel();
                            //data3.target_comm_no = rv.deviceCode;
                            //data3.ctrl_time = DateTime.Now;
                            //data3.ctrl_timeout = DateTime.Now.AddDays(3);
                            //data3.ctrl_type = "iotmeterv1.prepay.setprice";
                            //decimal price = (decimal)dto2.cmdParam.unitPrice.Value;
                            //data3.ctrl_data = new ladder_price() { price1 = price }.SerializerObjectToString();
                            //if (real == null || real.Price != price)
                            //{
                            //    list.Add(data3);
                            //}
                            //if (list.Count > 0)
                            //{
                            //    string sendFlag = Global.HttpIOTSend(apiInterface, list.SerializerObjectToString());
                            //    if (!string.IsNullOrWhiteSpace(sendFlag))
                            //    {
                            //        JObject jb2 = JObject.Parse(sendFlag);
                            //        if (jb2["State"].ToString() == "success")
                            //        {
                            //            mr.success = true;
                            //            mr.commandResult = "成功";
                            //        }
                            //    }
                            //}
                            //else
                            //{
                            //    mr.success = true;
                            //    mr.commandResult = "成功";
                            //}
                            //mr.sequence = dto2.sequence;
                            //mr.commandEndTime = DateTime.Now;
                            //bool cmdRr = Global.CommonSend("eciot-openapi/cmdResponse", mr, ref errMsg);
                            //WriteLog.WriteLogFile($"cmd Response : {cmdRr};msg:{errMsg};cmd value : {dto.ToString()}");
                            #endregion
                        }
                    }
                }
                else if (jb["meterCommandCode"].ToString() == "OPEN_VALVE"
                    || jb["meterCommandCode"].ToString() == "CLOSE_VALVE")
                {
                    ReqValveModel dto2 = dto.ToString().JSONStringToObject<ReqValveModel>();
                    mr.sequence = dto2.sequence;
                    mr.commandEndTime = DateTime.Now;
                    string conn = Global.Configuration["ConnectionStrings:DDb"];
                    using (Entity.DBContext context = Entity.BaseContext.CreateContext(conn))
                    {
                        MeterInfo v = context.meterInfos.Where(p => p.uniqueDeviceIdentifier == dto2.uniqueDeviceIdentifier).FirstOrDefault();
                        RTUInfo rv = context.rTUInfos.Where(p => p.uniqueDeviceIdentifier == dto2.uniqueDeviceIdentifier).FirstOrDefault();
                        if (v != null || rv != null)
                        {
                            string apiInterface = "api/Conf/CtrlData/Add";
                            CtrlCommandModel data = new CtrlCommandModel();
                            data.target_comm_no = (v == null ? rv.deviceCode : v.meterCode);
                            data.ctrl_time = DateTime.Now;
                            data.ctrl_timeout = DateTime.Now.AddDays(3);
                            if (jb["meterCommandCode"].ToString() == "OPEN_VALVE")
                            {
                                data.ctrl_type = "iotmeterv1.common.releaseforce";
                            }
                            else
                            {
                                data.ctrl_type = "iotmeterv1.common.setvalveoff";
                            }
                            string result = Global.HttpIOTSend(apiInterface, data.SerializerObjectToString());
                            if (!string.IsNullOrWhiteSpace(result))
                            {
                                JObject jb2 = JObject.Parse(result);
                                if (jb2["State"].ToString() == "success")
                                {
                                    ValveOperateInfo vo = new ValveOperateInfo();
                                    vo.ctrl_id = jb2["Data"].ToString();
                                    vo.sequence = dto2.sequence;
                                    vo.HuaRunData = dto.ToString();
                                    vo.SendFlag = 0;
                                    vo.CreateDate = DateTime.Now;
                                    context.valveOperateInfos.Add(vo);
                                    context.SaveChanges();
                                    rd.code = 200;
                                    mr.success = true;
                                    mr.commandResult = "成功";
                                }
                                else
                                {
                                    rd.code = 400;
                                    mr.commandResult = rd.msg = "命令未添加成功";
                                    bool cmdRr = Global.CommonSend("eciot-openapi/cmdResponse", mr, ref errMsg);
                                    WriteLog.WriteLogFile($"cmd Response : {cmdRr};msg:{errMsg};cmd value : {dto}");
                                }
                            }
                            else
                            {
                                rd.code = 400;
                                mr.commandResult = rd.msg = "命令未添加成功";
                                bool cmdRr = Global.CommonSend("eciot-openapi/cmdResponse", mr, ref errMsg);
                                WriteLog.WriteLogFile($"cmd Response : {cmdRr};msg:{errMsg};cmd value : {dto}");
                            }
                        }
                        else
                        {
                            rd.code = 400;
                            mr.commandResult = rd.msg = "没有找到相应设备";
                            bool cmdRr = Global.CommonSend("eciot-openapi/cmdResponse", mr, ref errMsg);
                            WriteLog.WriteLogFile($"cmd Response : {cmdRr};msg:{errMsg};cmd value : {dto}");
                        }
                    }
                }
                else
                {
                    rd.code = 400;
                    rd.msg = "此业务暂未开通";
                }
            }
            catch (Exception ex)
            {
                mr.commandEndTime = DateTime.Now;
                mr.commandResult = "失败";
                bool result = Global.CommonSend("eciot-openapi/cmdResponse", mr, ref errMsg);
                WriteLog.WriteLogFile($"cmdResponse : {result};msg:{errMsg}");
                rd.msg = ex.Message;
                rd.code = 500;
            }
            return rd;
        }


    }
    public class ladder_price
    {
        //价格1
        public decimal price1 { get; set; }
        //阶梯量1
        public decimal ladder1 { get; set; } = 0;
        //价格2
        public decimal price2 { get; set; }
        //阶梯量2
        public decimal ladder2 { get; set; }
        //价格3
        public decimal price3 { get; set; }
        //阶梯量3
        public decimal ladder3 { get; set; }
        //价格4
        public decimal price4 { get; set; }
        //阶梯量4
        public decimal ladder4 { get; set; }
        //价格5
        public decimal price5 { get; set; }
        //周期起始时间
        public DateTime cycle_start { get; set; }
        //周期月数
        public int cycle_month { get; set; }
    }
    public class ReqRemainMoneyModel
    {
        public string? appId { get; set; }
        public string? cacheCmdCode { get; set; }
        public string? sequence { get; set; }//String Y 业务序列
        public string? domainId { get; set; }//String Y 公司id
        public string? uniqueDeviceIdentifier { get; set; }// String Y 设备唯一标示符(表具注册时，通过回调方法返回的值)
        public string? commandTimeliness { get; set; }// String Y 命令时效性:WINDOW: 窗口命令REALTIME: 唤醒命令
        public string? meterCommandCode { get; set; }//   String Y   余额同步：SYNC_BALANCE
        public CmdParamModel? cmdParam { get; set; }//  Object Y   余额同步参数
    }

    public class CmdParamModel
    {
        public string? valveControlState { get; set; }// String  Y 阀门控制状态DEFAULT：默认不控阀OPEN：   开阀CLOSE：  关阀ALARM_CLOSE：  预警关阀
        public double? settlementBalance { get; set; }//  Double Y   结算余额，单位元，保留2位小数
        public double? settlementNum { get; set; }//  Double Y   结算读数
        public Int64? settlementTime { get; set; }// Date Y   结算时间
        public double? unitPrice { get; set; }// Double Y   单价，单位元，保留2位小数
        public double? recentRechargeAmount { get; set; }//  Double Y   最近一次的交费金额 ，单位元，保留2位小数
        public Int64? recentPaymentTime { get; set; }/// Date Y   最近一次的交费日期
        public int? calcSource { get; set; }
        public string? lastTimeUnitPrice { get; set; }//
        public string? lastTimeSurplus { get; set; }//
        public Int64? lastTimeSettlementDate { get; set; }//
    }

    public class ReqValveModel
    {
        public string? appId { get; set; }
        public string? cacheCmdCode { get; set; }
        public string? sequence { get; set; }//String Y 业务序列
        public string? domainId { get; set; }//String Y 公司id
        public string? uniqueDeviceIdentifier { get; set; }//String Y 设备唯一标示符(表具注册时，通过回调方法返回的值)
        public string? meterCommandCode { get; set; }//String Y 表具命令码:        开阀：OPEN_VALVE 关阀：CLOSE_VALVE
        public string? commandTimeliness { get; set; }//String Y   命令时效性:        WINDOW: 窗口命令REALTIME: 唤醒命令
        public ValveModel? cmdParam { get; set; }//Object N   业务参数(非必填)

    }
    public class ValveModel
    {
        public string? valveControlState { get; set; }//String N   阀门控制状态(根据表具命令码判断阀控:如果为空，则直接使用表具命令码生成命令) :        OPEN: 开阀(表具命令码:开阀)CLOSE: 关阀(表具命令码:关阀)ALARM_CLOSE: 预警关阀(表具命令码:关阀)
    }

    public class CtrlCommandModel
    {
        public CtrlCommandModel()
        {
            processor_name = "iotmeterv1";
            target_devtype = 1;
        }
        public int ctrl_id { get; set; }//Int AUTO_INCREMENT PRIMARY KEY 事物流水号
        public int upper_ctrl_id { get; set; }// int 上级系统事物流水号
        public string company_no { get; set; }//nvarchar(10)    项目公司编号，4个数字字符
        public string processor_name { get; set; }// nvarchar(50)    处理程序标识
        public string ctrl_define_no { get; set; }// nvarchar(50)    自定义命令编号
        public string target_comm_no { get; set; }// nvarchar(50)    目标通信编号
        public int target_devtype { get; set; }// int 目标设备类型 1-表计 2-RTU
        public DateTime ctrl_time { get; set; }// datetime 任务生成时间
        public DateTime ctrl_timeout { get; set; }//datetime    任务超时时间
        public int ctrl_state { get; set; }// int 任务状态
        public string ctrl_state_msg { get; set; }// nvarchar(50)    任务状态说明
        public string ctrl_feedback_msg { get; set; }// nvarchar(2000)  反馈信息
        public string ctrl_type { get; set; }// nvarchar(200)   任务类型
        public string ctrl_data { get; set; }//json 任务数据
        public string return_data { get; set; }//json    返回的响应数据
        public int sync_flag { get; set; }//int 同步标志,0-不需要同步,1-等待同步,2-同步完成
        public DateTime sync_time { get; set; }//Datetime 下次同步时间
        public string sync_msg { get; set; }// nvarchar(50)    同步信息
    }

    public class remote_charge_param
    {
        //5Byte当前充值量/金额
        public double charge_value { get; set; }
        //5Byte累计充值量/金额
        public double total_value { get; set; }
        //2HEX充值次数
        public int charge_times { get; set; }
    }
}
